package mypazar.customer;

import jason.environment.grid.Location;
import mypazar.agent.PersonAgent;
import mypazar.jenamodel.PazarVocabulary;
import mypazar.pazar.PazarModel;

import org.apache.log4j.Logger;

import tr.edu.ege.seagent.core.fipa.AgentIdentifier;
import tr.edu.ege.seagent.planner.htn.Action;
import tr.edu.ege.seagent.planner.htn.ExecutionMethod;
import tr.edu.ege.seagent.planner.htn.Outcome;
import tr.edu.ege.seagent.planner.htn.Provision;

import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;

/**
 * Action class of ACMoveTowards.
 */
public class ACMoveTowards extends Action {

	/**
	 * Location provision.
	 */
	@Provision
	private Location Location;

	/**
	 * Returns the value of the Location provision.
	 */
	public Location getLocation() {
		return this.Location;
	}

	/**
	 * Sets the value of the Location provision.
	 */
	public void setLocation(Location Location) {
		this.Location = Location;
	}

	/**
	 * SmanName provision.
	 */
	@Provision
	private String SmanName;

	/**
	 * Returns the value of the SmanName provision.
	 */
	public String getSmanName() {
		return this.SmanName;
	}

	/**
	 * Sets the value of the SmanName provision.
	 */
	public void setSmanName(String SmanName) {
		this.SmanName = SmanName;
	}

	/**
	 * SellerName outcome.
	 */
	@Outcome
	private String SellerName;

	/**
	 * Returns the value of the SellerName outcome.
	 */
	public String getSellerName() {
		return this.SellerName;
	}

	/**
	 * Sets the value of the SellerName outcome.
	 */
	public void setSellerName(String SellerName) {
		this.SellerName = SellerName;
	}

	private int agId = -1;

	private static Logger logger = Logger.getLogger(ACMoveTowards.class);

	/**
	 * Execution method.
	 * 
	 * @throws Exception
	 */
	@ExecutionMethod
	public void execute() {
		boolean done = false;
		this.setSellerName(getSmanName());
		Model beliefBase = (Model) getHeapValue(PersonAgent.BELIEF_BASE_ITEM_NAME);
		PazarModel model = (PazarModel) getHeapValue(PersonAgent.MODEL_ITEM_NAME);

		while (!done) {
			done = model.moveTowards(getAgId(), getLocation());
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		updatePersonLocation(beliefBase, PazarVocabulary.NS_URI
				+ getAgentIdentifier().toString().substring(0, 7),
				getLocation());

	}

	/**
	 * Updates person's new location on belief base.
	 * 
	 * @param beliefBase
	 * @param personURI
	 * @param currentLoc
	 */
	private void updatePersonLocation(Model beliefBase, String personURI,
			Location currentLoc) {
		Property posXProp = ResourceFactory
				.createProperty(PazarVocabulary.POS_X_URI);
		Property posYProp = ResourceFactory
				.createProperty(PazarVocabulary.POS_Y_URI);

		Resource resPerson = beliefBase.getResource(personURI);

		StmtIterator iterPerson = resPerson.listProperties(ResourceFactory
				.createProperty(PazarVocabulary.POSITION_URI));

		if (iterPerson.hasNext()) {
			Statement stmtPersonLoc = iterPerson.next();

			Resource resPersonLoc = stmtPersonLoc.getObject().asResource();

			resPersonLoc
					.removeAll(posXProp)
					.removeAll(posYProp)
					.addProperty(posXProp, Integer.toString(currentLoc.x),
							XSDDatatype.XSDint)
					.addProperty(posYProp, Integer.toString(currentLoc.y),
							XSDDatatype.XSDint);

			logger.info("After moved toward "
					+ getAgentIdentifier().toString().substring(0, 7)
					+ " is now on (" + currentLoc.x + "," + currentLoc.y + ")");

		}
	}

	/**
	 * Parses the agent number from its {@link AgentIdentifier} and returns it.
	 * 
	 * @return agent number.
	 */
	private int getAgId() {
		if (agId == -1) {
			agId = Integer.parseInt(getAgentIdentifier().toString().substring(
					6, 7)) - 1;
		}
		return agId;
	}

}
